package cn.buk.tms.dao;

import cn.buk.tms.entity.misc.SmsDetail;
import cn.buk.tms.entity.misc.SmsDetail_;
import cn.buk.tms.sc.SearchSmsCriteria;
import cn.buk.common.util.DateUtil;
import java.util.ArrayList;
import java.util.List;

import jakarta.persistence.criteria.*;
import jakarta.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Repository;

@Repository
@Transactional
public class SmsDaoImpl extends AbstractDao implements SmsDao {

  private static final Logger logger = LogManager.getLogger(SmsDaoImpl.class);

  @Override
  public int createSmsDetail(SmsDetail smsDetail) {
    em.persist(smsDetail);
    return 1;
  }

  @Override
  public int updateSmsStatus(int id, String sendStatus, String msgId) {
    return em.createQuery("update SmsDetail o set " +
        "o.sendStatus = :sendStatus, o.msgId = :msgId, o.lastUpdate = :lastUpdate " +
        "where o.id = :id")
        .setParameter("id", id)
        .setParameter("sendStatus", sendStatus)
        .setParameter("msgId", msgId)
        .setParameter("lastUpdate", DateUtil.getCurDateTime())
        .executeUpdate();
  }

  @Override
  public List<SmsDetail> searchSmsDetails(int enterpriseId, SearchSmsCriteria sc) {
    List<SmsDetail> results = null;

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<SmsDetail> cq = cb.createQuery(SmsDetail.class);
    Root<SmsDetail> root = cq.from(SmsDetail.class);
    root.alias("o");

    var predicates0 = getPredicates_searchSmsDetails(enterpriseId, sc, cb, root);


    //计算根据条件查询得出的数据总数
    CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
    Root<SmsDetail> countRoot = countQuery.from(SmsDetail.class);
    countRoot.alias("o");

    var predicates1 = getPredicates_searchSmsDetails(enterpriseId, sc, cb, countRoot);

    // count items
    countQuery.select(cb.count(countRoot))
        .where(predicates1.toArray(new Predicate[predicates1.size()]));
    Long count = em.createQuery(countQuery).getSingleResult();

    //查询
    cq.select(root).where(predicates0.toArray(new Predicate[predicates0.size()]));

    List<Order> orderByes = new ArrayList<>();
    orderByes.add(cb.desc(root.get("id")));

    cq.orderBy(orderByes);

    int maxResults = count.intValue();
    if (maxResults > 0) {
      sc.getPage().setRowCount(maxResults);

      results = em.createQuery(cq)
          .setFirstResult(sc.getPage().getFirstPosition())
          .setMaxResults(sc.getPage().getPageSize())
          .getResultList();

    }

    if (results == null) {
      results = new ArrayList<>();
    }

    return results;
  }

  private List<Predicate> getPredicates_searchSmsDetails(int enterpriseId, SearchSmsCriteria sc, CriteriaBuilder cb, Root<SmsDetail> root) {
    List<Predicate> predicates = new ArrayList<>();

    Predicate predicate = cb.conjunction();
    predicates.add(predicate);

    predicate = cb.equal(root.get(SmsDetail_.enterpriseId), enterpriseId);
    predicates.add(predicate);

    if (sc.getMobile().length() > 0) {
      predicate = cb.like(root.get(SmsDetail_.recvPhoneNo), "%" + sc.getMobile() + "%");
      predicates.add(predicate);
    }

    if (sc.getRemark().trim().length() > 0) {
      predicate = cb.like(root.get(SmsDetail_.smsContent), "%" + sc.getRemark().trim() + "%");
      predicates.add(predicate);
    }

    if (StringUtils.isNotBlank(sc.getUsername())) {
      predicate = cb.equal(root.get(SmsDetail_.operator), sc.getUsername());
      predicates.add(predicate);
    }

    if (sc.getBeginDate() == null) {
      //默认只能查2年内的
      predicate = cb.greaterThanOrEqualTo(root.get(SmsDetail_.createTime), getMinBeginDate());
      predicates.add(predicate);
    }
    return predicates;
  }

  @Override
  public List<SmsDetail> searchSmsByOrderNo(int enterpriseId, String orderNo) {
    return em.createQuery(
        "select o from SmsDetail o where o.enterpriseId = :enterpriseId and o.orderNo = :orderNo order by o.id desc",
        SmsDetail.class)
        .setParameter("enterpriseId", enterpriseId)
        .setParameter("orderNo", orderNo)
        .getResultList();
  }

  @Override
  public int saveReceivedSms(int enterpriseId, String mobile, String content, String orderNo) {
    SmsDetail sms = new SmsDetail();
    sms.setEnterpriseId(enterpriseId);
    sms.setSmsType(1);
    sms.setRecvPhoneNo(mobile);
    sms.setSmsContent(content);
    sms.setOrderNo(orderNo);

    em.persist(sms);
    em.flush();

    return sms.getId();
  }

}
